#include "../../include/ParticleEmitter.hpp"
#include "../../include/Utils.hpp"
#include <iostream>

using namespace std;
using namespace klas;

// Change the position of the emitter and set the maximum particles.
ParticleEmitter::ParticleEmitter(const Vector2<Real>& posA, const Vector2<Real>& posB, Real maxParticles)
{
  m_particles.resize(maxParticles);
  m_emitterPos.min = posA;
  m_emitterPos.max = posB;
  m_emitParticles = true;
  m_maxParticles = maxParticles;
  m_texture = NULL;
	m_velocity.min = Vector2<Real>(-2, -2);
	m_velocity.max = Vector2<Real>(2, 2);
	m_dampening.min = .98;
	m_dampening.max = .99;
	m_creationRate.min = 10;
	m_creationRate.max = 20;
	m_lifeSpan.min = 2;
	m_lifeSpan.max = 4;
	m_initialScale.min = .8;
	m_initialScale.max = 1.2;
	m_finalScale.min = .2;
	m_finalScale.max = .4;
	m_initialCol = Color(1, 1, 1, 1);
	m_endCol = Color(0, 0, 0, 0);

}

ParticleEmitter::~ParticleEmitter()
{
}

/* ------------------- */
/* set / get functions */
void ParticleEmitter::setPos(const Vector2<Real>& posA, const Vector2<Real>& posB)
{
  m_emitterPos.min = posA;
  m_emitterPos.max = posB;
}

void ParticleEmitter::setTexture(void* texture)
{
  m_texture = (Texture*)texture;
}

void ParticleEmitter::setColors(const Color& initial, const Color& final)
{
  m_initialCol = initial;
  m_endCol = final;
}

void ParticleEmitter::setVelocities(const Vector2<Real>& min, const Vector2<Real>& max)
{
  m_velocity.min = min;
  m_velocity.max = max;
}

void ParticleEmitter::setDampening(Real min, Real max)
{
  m_dampening.min = min;
  m_dampening.max = max;
}

void ParticleEmitter::setCreationRate(iReal min, iReal max)
{
  m_creationRate.min = min;
  m_creationRate.max = max;
}

void ParticleEmitter::setLifeSpan(Real min, Real max)
{
  m_lifeSpan.min = min;
  m_lifeSpan.max = max;
}

void ParticleEmitter::setScale(Real initialMin, Real initialMax, Real finalMin, Real finalMax)
{
  m_initialScale.min = initialMin;
  m_initialScale.max = initialMax;
  m_finalScale.min = finalMin;
  m_finalScale.max = finalMax;
}

void ParticleEmitter::setMaxParticles(iReal max)
{
  m_maxParticles = max;
}

/* ------------- */


// Updates our particles
void ParticleEmitter::updateParticles(Real dt)
{  
  int remainingParticles = Utils::random(m_creationRate.min, m_creationRate.max);
  m_activeParticles = 0;
  for(unsigned int i = 0; i < m_particles.size(); i++)
  {

    if(m_particles[i].isDead() == false)
  	{
      m_particles[i].update(dt, Utils::random(m_dampening.min, m_dampening.max));
      ++m_activeParticles;
  	}
  	else
  	{
      if(m_emitParticles && remainingParticles >= 0)
  		{
         --remainingParticles;
         ++m_activeParticles;
	
  				Vector2<Real> randomVelocity;
  				randomVelocity.x = Utils::random(m_velocity.min.x, m_velocity.max.x);
    			randomVelocity.y = Utils::random(m_velocity.min.y, m_velocity.max.y);
    			
    			Vector2<Real> randomPos;
    			randomPos.x = Utils::random(m_emitterPos.min.x, m_emitterPos.max.x);
    			randomPos.y = Utils::random(m_emitterPos.min.y, m_emitterPos.max.y);
    		
    			m_particles[i].recreate(Utils::random(m_lifeSpan.min, m_lifeSpan.max),
    								Utils::random(m_initialScale.min, m_initialScale.max),
    								Utils::random(m_finalScale.min, m_finalScale.max),
    								randomVelocity,
    								randomPos,
    								m_initialCol,
    								m_endCol,
    								m_texture); 
  	 		
  	 							
    	}
  	}
  }
}

void ParticleEmitter::render(const Camera& cam)
{
	Vector2<Real> camPos;
	camPos.x = cam.getRect().x1;
	camPos.y = cam.getRect().y1;
		
  for(unsigned int i = 0; i < m_particles.size(); i++)
    if(m_particles[i].isDead() == false)
      m_particles[i].render(camPos);
}

iReal ParticleEmitter::getParticleCount() const
{
  return m_activeParticles;
}

void ParticleEmitter::shouldEmit(bool emit)
{
  m_emitParticles = emit;
}
